﻿using System;
using System.Text;
using System.Web.UI.WebControls;
using BoldBrick.Core.Logging;
using BoldBrick.SharePoint.CommonControls.DataObjects.Query;
using BoldBrick.SharePoint.CommonControls.Resources;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace BoldBrick.SharePoint.CommonControls.Layouts
{
	public abstract class BaseDialogPage : LayoutsPageBase
	{
		private static readonly ILogger log = Logger.GetLogger(typeof(BaseDialogPage));

		private ListItemPageQueryParameters queryParameters;
		protected ListItemPageQueryParameters QueryParameters
		{
			get
			{
				if (queryParameters == null)
				{
					queryParameters = ListItemPageQueryParameters.GetParametersFromContext();
				}
				return queryParameters;
			}
		}
		

		protected DialogIconTypes? DialogIconType
		{
			get
			{
				DialogMaster dialogMaster = this.Master as DialogMaster;
				if (dialogMaster == null)
				{
					log.Write(LogLevel.Error, "Master page is not DialogMaster: {0}", this.Context.Request.Url);
					return null;
				}
				return dialogMaster.DialogIconType;
			}
			set
			{
				DialogMaster dialogMaster = this.Master as DialogMaster;
				if (dialogMaster == null)
				{
					log.Write(LogLevel.Error, "Master page is not DialogMaster: {0}", this.Context.Request.Url);
					return;
				}
				if (value.HasValue)
				{
					dialogMaster.DialogIconType = value.Value;
				}
				
			}
		}

		#region ------ Load & Setup Page ----------------------------------------------------------

		protected override void OnLoad(EventArgs e)
		{
			SetupDialog();

			base.OnLoad(e);
		}

		/// <summary>
		/// Setups dialog, sets resources, events, etc.
		/// </summary>
		private void SetupDialog()
		{
			DialogMaster dialogMaster = this.Master as DialogMaster;
			if (dialogMaster == null)
			{
				log.Write(LogLevel.Error, "Master page is not DialogMaster: {0}", this.Context.Request.Url);
				return;
			}

			uint language = SPContext.Current.Web.Language;

			// OK button
			Button buttonOK = dialogMaster.OkButton;
			buttonOK.Text = GetOKButtonText(language);
			buttonOK.Click += new EventHandler(buttonOK_Click);

			// Cancel button
			dialogMaster.CancelButton.Text = GetCancelButtonText(language);

			// Title
			string title = GetTitle(language);
			if (!string.IsNullOrEmpty(title))
			{
				this.Title = title;
			}

			// description
			string description = GetDescription(language);
			if (!string.IsNullOrEmpty(description))
			{
				dialogMaster.Description = description;
			}
		}

		/// <summary>
		/// Gets description of the dialog
		/// </summary>
		/// <param name="language">Language identifier</param>
		/// <returns>Returns description of the dialog</returns>
		protected abstract string GetDescription(uint language);

		/// <summary>
		/// Gets "Cancel" button text of the dialog
		/// </summary>
		/// <param name="language">Language identifier</param>
		/// <returns>Returns "Cancel" button text of the dialog</returns>
		protected abstract string GetCancelButtonText(uint language);

		/// <summary>
		/// Gets "OK" button text of the dialog
		/// </summary>
		/// <param name="language">Language identifier</param>
		/// <returns>Returns "OK" button text of the dialog</returns>
		protected abstract string GetOKButtonText(uint language);

		/// <summary>
		/// Gets title of the dialog
		/// </summary>
		/// <param name="language">Language identifier</param>
		/// <returns>Returns title of the dialog</returns>
		protected abstract string GetTitle(uint language);

		#endregion

		#region ------ Lists Methods --------------------------------------------------------------

		/// <summary>
		/// Gets list for this dialog
		/// </summary>
		/// <param name="language">Language identifier</param>
		/// <returns>Returns list for this dialog</returns>
		protected SPList GetList(uint language)
		{
			if (!QueryParameters.ListID.HasValue)
			{
				log.Write(LogLevel.Error, "No list id provided.");
				return null;
			}

			return SPContext.Current.Web.Lists[QueryParameters.ListID.Value];
		}

		/// <summary>
		/// Gets list item passed to the dialog page (if list of items is passed, this is the first one)
		/// </summary>
		/// <param name="language">Lanugage identifier</param>
		/// <returns>Returns list item passed to the dialog page (if list of items is passed, this is the first one)</returns>
		protected SPListItem GetListItem(uint language)
		{
			// get list
			SPList list = GetList(language);
			if (list == null)
			{
				string message = ResourceBuilder.GetResource("BaseDialogPage_Error_NoList", language);
				ShowError(message, true);
				return null;
			}

			// get item IDs
			if (QueryParameters.Items == null || QueryParameters.Items.Length == 0)
			{
				string message = ResourceBuilder.GetResource("BaseDialogPage_Error_NoItemID", language);
				ShowError(message, true);
				log.Write(LogLevel.Error, message);
				return null;
			}

			int itemID = QueryParameters.Items[0];
			SPListItem item = list.GetItemById(itemID);
			if (item == null)
			{
				string message = ResourceBuilder.GetResource("BaseDialogPage_Error_NoItem", language);
				ShowError(message, true);
				log.Write(LogLevel.Error, "Item with '{0}' not found in '{1}' list.", itemID, list.RootFolder.ServerRelativeUrl);
				return null;
			}

			return item;
		}

		#endregion

		#region ------ Action Methods -------------------------------------------------------------

		/// <summary>
		/// True is actio is passed, otherwise false
		/// </summary>
		private bool actionPassed;

		/// <summary>
		/// Performs action after click on "OK" button
		/// </summary>
		/// <param name="errorMessage">Error message of the action</param>
		/// <returns>Returns true is action is done well, otherwise returns false</returns>
		protected abstract bool DoAction(out string errorMessage);

		/// <summary>
		/// Operation that starts during click on "OK" button
		/// </summary>
		private void DoActionCore()
		{
			string errorMessage;
			if (!DoAction(out errorMessage))
			{
				if (!string.IsNullOrEmpty(errorMessage))
				{
					ShowError(errorMessage, true);
				}

				return;
			}

			actionPassed = true;
		}

		private string urlToRedirect;
		private bool showInDialogWindow;

		/// <summary>
		/// Redirects to another URL
		/// </summary>
		/// <param name="url">URL to redirect</param>
		/// <param name="showInDialog">Set true is URL to redirect has to shown in dialog window.</param>
		protected void Redirect(string url, bool showInDialog)
		{
			actionPassed = true;
			this.urlToRedirect = url;
			this.showInDialogWindow = showInDialog;
		}

		protected override void Render(System.Web.UI.HtmlTextWriter writer)
		{
			base.Render(writer);

			// actions is passed, close dialog with OK result
			if (actionPassed)
			{
				StringBuilder sb = new StringBuilder();
				sb.AppendLine("<script type='text/javascript'>");
				sb.AppendLine("var results = new Object();");

				// if URL to redirect is set add this URL to results
				if (!string.IsNullOrEmpty(urlToRedirect))
				{
					sb.AppendFormat("results.url = '{0}';", urlToRedirect);
					sb.AppendFormat("results.showInDialog = {0};", showInDialogWindow.ToString().ToLower());
				}

				sb.AppendLine("SP.UI.ModalDialog.commonModalDialogClose(1, results);");
				sb.AppendLine("</script>");

				writer.Write(sb);
			}
		}

		#endregion

		#region ------ Common Methods -------------------------------------------------------------

		/// <summary>
		/// Shows error message in this dialog
		/// </summary>
		/// <param name="message">Error message to show</param>
		/// <param name="hideOkButton">Set true for hiding of "OK" button, otherwise set false</param>
		protected void ShowError(string message, bool hideOkButton)
		{
			DialogMaster dialogMaster = this.Master as DialogMaster;
			if (dialogMaster == null)
			{
				log.Write(LogLevel.Error, "Master page is not DialogMaster: {0}", this.Context.Request.Url);
				return;
			}

			dialogMaster.Description = message;
			dialogMaster.DialogIconType = DialogIconTypes.Error;
			dialogMaster.CancelButton.Text = ResourceBuilder.GetResource("BaseDialogPage_CancelButton_OKText", SPContext.Current.Web.Language);

			dialogMaster.OkButton.Visible = !hideOkButton;
		}

		#endregion
		

		#region ------ Events ---------------------------------------------------------------------

		private void buttonOK_Click(object sender, EventArgs e)
		{
			DoActionCore();
		}

		#endregion
	}

	
}
